#!/bin/sh
#(c) Copyright Barry Kauler 2010, bkhome.org
#Lesser GPL license v2 (/usr/share/doc/legal/lgpl-2.1.txt
#note, 3builddistro (in Woof) renames rootfs-skeleton/sbin/initNEW to init.
#perform a f.s. check if file /fsckme.flg exits, otherwise normal startup.
#/etc/rc.d/rc.sysinit creates /fsckme.flg at bootup, rc.shutdown deletes it.
#this script is /sbin/init in the main Puppy f.s., which is the very first to run.
#in the case of not a full hd install, this script just passes execution to busybox init.
#100911 fsckme.err filename changed to fsckme.flg. see also init (initramfs), rc.sysinit, rc.shutdown.
#101020 no longer have /etc/modprobe.conf.
#120408 support minit
#120516 gentoo: libgcc_s.so.1 in wrong place.
#120627 check ramdisk big enough.
#120716 revert 120627, /sys not yet loaded. do it a different way. fix for weird 'tr' missing.
#120716 raspi: no battery-backed hardware clock, so date is wrong, workaround. fixes for rc.sysinit in ramdisk.
#120717 f.s. maximal mount count reached, perform f.s. check.
#120718 try force unmount.
#120729 needed to unmount /old_root/dev, as raspi kernel configured to automount fs on /dev.
#130203 /bin/probedisk2 now /bin/probedisk only.
#130418 support kmod (replaces module-init-tools).

INITEXE='/bin/busybox init'
[ -f /sbin/minit ] && INITEXE='/sbin/minit'

[ -d /initrd ] && exec ${INITEXE} #not a full hd install.
[ -f /var/tmp/initrd_full_install_flag ] && exec ${INITEXE} #full install with initrd

#=========================================
#      full install (without initrd)
#=========================================

if [ "$pfix" ];then
 for ONEFIX in $(echo -n "$pfix" | tr ',' ' ')
 do
  case $ONEFIX in
   xorgwizard) PXORGWIZARD="yes";;#force xorgwizard for this session
   nox)     PNOX="yes";;          #do not start X.
   fsck)    PFSCK="yes";;         #do a fsck of ${DISTRO_FILE_PREFIX}save file.
   fsckp)   PFSCKP="yes";;        #do fsck before first mount of ext partitions
  esac
 done
fi

[ "$PXORGWIZARD" = "yes" ] && touch /tmp/xwin_xorgwizard_cli
[ "$PNOX" = "yes" ] && touch /tmp/bootcnt.txt

if [ -f /etc/DISTRO_SPECS ] ; then
  . /etc/DISTRO_SPECS
  clear > /dev/console
  echo -en "\\033[0;34m***\\033[0;37m ${DISTRO_NAME} ${DISTRO_VERSION}" >/dev/console
  echo -en "\\033[0;34m -\\033[0;37m Linux `uname -r` " >/dev/console
  echo -en "\\033[0;31m[\\033[0;37m`uname -m`\\033[0;31m]" >/dev/console
  echo -e "\\033[0;34m ***\\033[0;39m" >/dev/console
fi

[ ! -e /fsckme.flg ] && exec ${INITEXE} #no error.

[ ! -f /var/local/ram_size_bytes ] && exec ${INITEXE} #created in rc.sysinit
if [ `cat /var/local/ram_size_bytes` -lt 20000 ];then #was 32768
 rm -f /fsckme.flg
 exec ${INITEXE} #unable to do f.s. check.
fi

#------- have to create a ram disk to check f.s.

PATH='/bin:/sbin'
export LANG=C

#only come here if full hd install, and previous improper shutdown.
PDEV1="`cat /fsckme.flg | cut -f 1 -d ','`" #file format: sda1,ext3,
DEV1FS="`cat /fsckme.flg | cut -f 2 -d ','`"
CHECK="`cat /fsckme.flg | cut -f 3 -d ','`" #120717 see rc.shutdown.
case $DEV1FS in
 ext2|ext3|ext4)
  echo -e "\\033[1;31m"  >/dev/console #34=blue, 33=yellow, 32=green, 31=red, 35=purple, 36=aquablue, 38=black.
  if [ "$CHECK" = "MAXIMAL" ];then #120717
   echo "Performing filesystem check of '${PDEV1}', maximal mount count" > /dev/console
  else
   echo "Performing filesystem check of '${PDEV1}' after improper shutdown" > /dev/console
  fi
  echo -n "NOTE: no progress indication, may take awhile, please wait patiently..."
  echo -e "\\033[0;39m" >/dev/console
  echo  >/dev/console
  busybox mount -t proc none /proc
  busybox mount -o remount,rw /
  rm -f /fsckme.flg
  #creat a ramdisk... 
  #note, Puppy kernels are compiled with 13MB ramdisk, so need to be careful not to fill it up...
  echo 'Creating a ramdisk and populating with a Linux environment...'  >/dev/console
  mkfs.ext2 -q -m 0 /dev/ram0
  mkdir -p /mnt/ram0
  busybox mount -t ext2 /dev/ram0 /mnt/ram0
  #populate the ramdisk...
  mkdir -p /mnt/ram0/old_root
  mkdir /mnt/ram0/bin
  for ONEBIN in "[" "[[" ash autologinroot basename busybox cat chmod chown clear cp cut date dc dd df dirname dmesg du ed expr false find free grep head kill ln login ls lsmod mkdir mknod more mv nice ntfs-3g pidof pwd readlink rev rm rmdir sed sleep sort stat su sync tail tar touch tr true uname usleep waitmax wc which xargs
  do
   if [ -e /bin/$ONEBIN ];then
    cp -a /bin/$ONEBIN /mnt/ram0/bin/
   else
    ln -s busybox /mnt/ram0/bin/$ONEBIN
   fi
  done
  ln -snf busybox /mnt/ram0/bin/ps
  ln -snf busybox /mnt/ram0/bin/rdev
  ln -snf busybox /mnt/ram0/bin/sh
  ln -snf busybox /mnt/ram0/bin/mount
  ln -snf busybox /mnt/ram0/bin/umount
  mkdir /mnt/ram0/sbin
  for ONEBIN in depmod dumpe2fs e2fsck elspci fdisk freeramdisk fsck.ext2 fsck.ext3 fsck.ext4 getty guess_fstype halt hdparm hotplug2stdout hotplug2stdout_notimeout hwclock ifconfig ifplugstatus insmod klogd kmod ldconfig loadkmap losetup lsmod mingetty mount.ntfs-3g pivot_root probedisk probepart swapon #130418
  do
   if [ -e /sbin/$ONEBIN ];then
    cp -a /sbin/$ONEBIN /mnt/ram0/sbin/
   else
    ln -s ../bin/busybox /mnt/ram0/sbin/$ONEBIN
   fi
  done
  ln -snf ../bin/busybox /sbin/chroot          #must match
  ln -snf ../bin/busybox /mnt/ram0/sbin/chroot #must match
  ln -snf ../bin/busybox /mnt/ram0/sbin/init
  ln -snf ../bin/busybox /mnt/ram0/sbin/poweroff
  ln -snf ../bin/busybox /mnt/ram0/sbin/reboot
  mkdir /mnt/ram0/etc
  #101020 no longer have /etc/modprobe.conf...
  for ONEFILE in codepage DISTRO_SPECS eventmanager fdprm floppy fontmap group gshadow host.conf hostname hosts hosts.allow hosts.deny inittab inoutrc issue keymap localtime mailcap mime.types mke2fs.conf modules.conf mtab networks nscd.conf nsswitch.conf passwd printcap protocols services shadow
  do
   cp -a /etc/$ONEFILE /mnt/ram0/etc/ 2>/dev/null
  done
  cp -a /etc/modprobe.d /mnt/ram0/etc/ 2>/dev/null #101020
  echo '/lib' > /mnt/ram0/etc/ld.so.conf
  echo 'export PATH="/bin:/sbin"
export LD_LIBRARY_PATH="/lib"
ulimit -c 0
umask 022
export USER=root
export LOGNAME=root
export TERM=linux' > /mnt/ram0/etc/profile
  LOCALTIME="/usr/share`readlink /etc/localtime | sed 's%^.*/zoneinfo%/zoneinfo%'`"
  LOCALTDIR="`dirname $LOCALTIME`"
  mkdir -p /mnt/ram0/$LOCALTDIR
  cp -a $LOCALTIME /mnt/ram0/$LOCALTDIR/
  mkdir /mnt/ram0/etc/rc.d
  #120716 raspi: no battery-backed hardware clock, so date is wrong...
  mkdir -p /mnt/ram0/var/local/
  #120718 find the date...
  HWDATE0="`hwclock --show 2>/dev/null`" #ex: Fri 29 Jun 2012 07:45:28 AM WST  -0.725833 seconds
  if [ "$HWDATE0" = "" ];then
   if [ -f /var/local/shutdown_date_saved ];then #see /etc/rc.d/rc.shutdown
    HWDATE1="`cat /var/local/shutdown_date_saved`"
   else
    #either of these formats can set the date: '29 JUN 2012 10:00:00' '2012-06-28 16:20:08'
    #120718 busybox date says '29 JUN 2012 10:00:00' invalid format
    HWDATE1="`stat --format=%z /etc/DISTRO_SPECS | cut -f 1 -d '.' | cut -f 1,2 -d ' '`" #creation date of build. ex: '2012-06-28 16:20:08'
   fi
   HWDATE0="$HWDATE1"
  fi
  echo "#!/bin/sh
echo 'Now running in ramdisk, performing filesystem check of ${PDEV1}...'
/bin/busybox mount -t proc none /proc
HWDATE=\"\`/sbin/hwclock --show 2>/dev/null\`\" #ex: Fri 29 Jun 2012 07:45:28 AM WST  -0.725833 seconds
if [ \"${HWDATE0}\" != \"\" ];then
 /bin/date -s \"${HWDATE0}\"
else
 /sbin/hwclock --hctosys --localtime
fi
/bin/busybox umount /old_root/dev 2>/dev/null #if kernel configured to mount fs on /dev
/bin/busybox umount /old_root
if [ \$? -ne 0 ];then
 echo 'Not so good, was unable to unmount ${PDEV1}. Trying forced unmount...'
 /bin/busybox umount -f /old_root #120718 try force unmount.
 if [ \$? -ne 0 ];then
  echo 'Unable to unmount, aborting filesystem check.'
 else
  echo 'Unmount successful, continuing with f.s. check...'
  UMOUNTFLAG='yes'
 fi
else
 UMOUNTFLAG='yes'
fi
if [ \"\$UMOUNTFLAG\" = \"yes\" ];then
 /sbin/e2fsck -p -f /dev/${PDEV1}
 /bin/busybox sync
 echo 'Filesystem check completed!'
fi
echo 'The computer now has to be restarted.'
echo 'Computer will reboot in 4 minutes, else press ENTER for immediate reboot.'
echo \"(Developers only: press 'c' then ENTER for shell in ramdisk)\"
echo
echo -n 'Press ENTER key to reboot:'
read -t 240 abcdef
[ \"\$abcdef\" = \"c\" ] && exit #go to shell in ramdisk.
/bin/busybox umount /proc
/bin/busybox reboot" > /mnt/ram0/etc/rc.d/rc.sysinit
  chmod 755 /mnt/ram0/etc/rc.d/rc.sysinit
  cp -a /dev /mnt/ram0/
  mkdir /mnt/ram0/lib
  cp -a /lib/lib*.so* /mnt/ram0/lib/
  cp -a /lib/ld*.so* /mnt/ram0/lib/
  [ ! -e /mnt/ram0/lib/libgcc_s.so.1 ] && cp -a -f --remove-destination /usr/lib/libgcc_s.so.* /mnt/ram0/lib/ 2>/dev/null #120516 gentoo fix.
  cp -a /lib/e2initrd_helper /mnt/ram0/lib/ 2>/dev/null #dunno what this is.
  mkdir /mnt/ram0/tmp
  mkdir -p /mnt/ram0/var/run
  mkdir /mnt/ram0/proc
  mkdir -p /mnt/ram0/usr/share
  cp -a /usr/share/terminfo /mnt/ram0/usr/share/
  #cleanup files...
  rm -f /var/log/X*
  rm -rf /tmp/*
  rm -f /var/lock/LCK*
  rm -f /var/run/*.pid
  rm -rf /root/tmp 2>/dev/null
  rm -rf /root/.thumbnails/* 2>/dev/null
  #120716 weird bug raspi, can't find 'tr', so use 'busybox tr'...
  rm -f `find /var -mount -type s | busybox tr '\n' ' '` #remove sockets.
  rm -f `find /var -mount -type p | busybox tr '\n' ' '` #remove pipes.
  sync
  #pivot_root to the ramdisk...
  echo 'Performing a pivot_root to the ramdisk...'  >/dev/console
  busybox mount -o remount,ro /
  busybox umount /proc
  cd /mnt/ram0
  pivot_root . old_root
  exec chroot . sh -c "exec /bin/busybox init" <dev/console >dev/console 2>&1
  #...the ramdisk is setup so that /etc/rc.d/rc.sysinit will run, which does the f.s. check.
 ;;
 *)
  echo -e "\\033[1;31m"  >/dev/console #34=blue, 33=yellow, 32=green, 31=red, 35=purple, 36=aquablue, 38=black.
  echo -n "Previous improper shutdown, sorry can only do f.s. check of ext2/3/4. Rebooting..." > /dev/console
  echo -e "\\033[0;39m" >/dev/console
  sleep 5
  exec ${INITEXE}
 ;;
esac

###END###
